
#include <kogi/list.h>

#include <attest/attest.h>

#include <stdio.h>
#include <string.h>

ATTEST(list, create)
{
    struct kogi_list list;
    memset(&list, 1, sizeof(list));
    ATTEST_EQ(0, kogi_list_create(&list));
    ATTEST_EQ(&(list.tail), list.head.next);
    ATTEST_EQ(&(list.head), list.tail.prev);
    ATTEST_EQ(NULL, list.head.prev);
    ATTEST_EQ(NULL, list.tail.next);
    ATTEST_EQ(0, list.size);
    ATTEST_EQ(0, kogi_list_size(&list));
    ATTEST_TRUE(kogi_list_empty(&list));
    ATTEST_EQ(0, kogi_list_destroy(&list));
}

ATTEST(list, push_back)
{
    struct kogi_list list;
    kogi_list_create(&list);
    for (int i = 1; i != 100; ++i)
    {
        ATTEST_EQ(0, kogi_list_push_back(&list, kogi_from_int(i)));
        ATTEST_EQ(1, kogi_to_int(kogi_list_front(&list)));
        ATTEST_EQ(i, kogi_to_int(kogi_list_back(&list)));
        ATTEST_EQ(i, (int)kogi_list_size(&list));
        ATTEST_FALSE(kogi_list_empty(&list));
    }
    ATTEST_EQ(0, kogi_list_destroy(&list));
}

ATTEST(list, push_back_double)
{
    struct kogi_list list;
    kogi_list_create(&list);
    for (double d = 1.3; d < 100; ++d)
    {
        ATTEST_EQ(0, kogi_list_push_back(&list, kogi_from_double(d)));
        ATTEST_EQ(1.3, kogi_to_double(kogi_list_front(&list)));
        ATTEST_EQ(d, kogi_to_double(kogi_list_back(&list)));
        ATTEST_EQ((size_t)d, kogi_list_size(&list));
        ATTEST_FALSE(kogi_list_empty(&list));
    }
    ATTEST_EQ(0, kogi_list_destroy(&list));
}

ATTEST(list, push_front)
{
    struct kogi_list list;
    kogi_list_create(&list);
    for (int i = 1; i != 100; ++i)
    {
        ATTEST_EQ(0, kogi_list_push_front(&list, kogi_from_int(i)));
        ATTEST_EQ(i, kogi_to_int(kogi_list_front(&list)));
        ATTEST_EQ(1, kogi_to_int(kogi_list_back(&list)));
        ATTEST_EQ(i, (int)kogi_list_size(&list));
        ATTEST_FALSE(kogi_list_empty(&list));
    }
    ATTEST_EQ(0, kogi_list_destroy(&list));
}

